package com.jy.event.controller;

import com.jy.event.dao.OrderDao;
import com.jy.event.dao.StoreDao;
import com.jy.event.dao.StorePayDao;
import com.jy.event.domain.ElectronicBill;
import com.jy.event.domain.Store;
import com.jy.event.domain.StorePay;
import com.jy.event.enums.OrderPayChannel;
import com.jy.event.service.ElectronicBillService;
import com.jy.event.service.Payservice;
import com.jy.event.util.JodaUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import static com.jy.event.enums.OrderPayChannel.HUI_SHANG;

@Slf4j
@RestController
@RequestMapping(value = "bill", produces = "application/json;charset=utf-8")
public class TestController {
    @Autowired
    StoreDao storeDao;
    @Autowired
    Payservice payservice;
    @Autowired
    ElectronicBillService electronicBillService;
    @Autowired
    OrderDao orderDao;
    @Autowired
    private StorePayDao storePayDao;

    @GetMapping("async")
    public ResponseEntity asyncDateBill(@RequestParam("storeId") String storeId, @RequestParam("date") String date) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        asyncStoreDateBill(date, formatter.parse(date), storeDao.findOne(storeId));
        return ResponseEntity.ok().body("OK");
    }

    @GetMapping("range")
    public ResponseEntity rangeDateBill(@RequestParam("storeId") String storeId, @RequestParam("startDate") String startDate, @RequestParam("endDate") String endDate) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        Store store = storeDao.findOne(storeId);
        List<ElectronicBill> bills = new ArrayList<>();

        Date d1 = formatter.parse(startDate);
        Date d2 = formatter.parse(endDate);
        Date tmp = d1;
        Calendar dd = Calendar.getInstance();
        dd.setTime(d1);

        while (tmp.getTime() < d2.getTime()) {
            tmp = dd.getTime();
            System.out.println(formatter.format(tmp));

            asyncStoreDateBill(formatter.format(tmp), tmp, store);
            // 天数加上1
            dd.add(Calendar.DAY_OF_MONTH, 1);
        }

        return ResponseEntity.ok(bills);
    }

    @GetMapping("date")
    public ResponseEntity date(@RequestParam("date") String date) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        asyncDateBill(date, formatter.parse(date));
        return ResponseEntity.ok("OK");
    }

    @GetMapping("date-range")
    public ResponseEntity dateRange(@RequestParam("startDate") String startDate, @RequestParam("endDate") String endDate) throws ParseException {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
        Date d1 = formatter.parse(startDate);
        Date d2 = formatter.parse(endDate);
        Date tmp = d1;
        Calendar dd = Calendar.getInstance();
        dd.setTime(d1);

        while (tmp.getTime() < d2.getTime()) {
            tmp = dd.getTime();
            System.out.println(formatter.format(tmp));

            asyncDateBill(formatter.format(tmp), tmp);
            // 天数加上1
            dd.add(Calendar.DAY_OF_MONTH, 1);
        }
        return ResponseEntity.ok("OK");
    }

    private void asyncDateBill(String billDate, Date saveDate) {
        List<StorePay> storePays = storePayDao.findAllByMchIdIsNotNullAndStartEnabledIsTrue();
        for (StorePay storePay : storePays) {
            try {
                if (StringUtils.isEmpty(StringUtils.trim(storePay.getMchId())) || storePay.getMchId().length() < 5)
                    continue;
                Store store = storeDao.findOne(storePay.getStoreId());
                if (null == store) continue;
                asyncStoreDateBill(billDate, saveDate, store);
            } catch (Exception ex) {
                log.error(" electronicBill run is error:{},store:{}", storePay, ex);
            }
        }
    }

    private void asyncStoreDateBill(String billDate, Date saveDate, Store store) {
        List<OrderPayChannel> channels = orderDao.findPayChannelByTime(JodaUtils.getStartOfYesterdayDate(), JodaUtils.getEndOfYesterdayDate());
        if (channels.contains(null) && channels.contains(HUI_SHANG)) {
            channels.remove(null);
        }
        channels.forEach(channel -> {
            if (null == channel) {
                saveElectronicBill(billDate, saveDate, store);
            } else {
                switch (channel) {
                    case HUI_SHANG:
                        saveElectronicBill(billDate, saveDate, store);
                        break;
                    case JL:
                        break;
                    case SAO_BEI:
                        break;
                    case SUI_XIN_FU:
                        try {
                            saveSuiXinFuBill(billDate, saveDate, store);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                }
            }
        });
    }

    private ElectronicBill saveElectronicBill(String billDate, Date saveDate, Store store) {
        StorePay channel = storePayDao.findTop1ByStoreIdAndChannel(store.getId(), HUI_SHANG);
        if (null == channel || StringUtils.isBlank(channel.getMchId())) {
            log.error(" electronicBill run is error: can't found channel {}, store:{}", HUI_SHANG, store);
            return null;
        }
        ElectronicBill electronicBill = payservice.electronicBill(store.getId(), channel.getMchId(), channel.getMchKey(), billDate, saveDate);
        if (electronicBill == null) {
            return null;
        }
        electronicBillService.saveChack(electronicBill, store.getName());
        return electronicBill;
    }

    private ElectronicBill saveSuiXinFuBill(String billDate, Date saveDate, Store store) throws Exception {
        StorePay channel = storePayDao.findTop1ByStoreIdAndChannel(store.getId(), OrderPayChannel.SUI_XIN_FU);
        if (null == channel || StringUtils.isBlank(channel.getMchId())) {
            log.error(" electronicBill run is error: can't found channel {}, store:{}", OrderPayChannel.SUI_XIN_FU, store);
            return null;
        }
        ElectronicBill electronicBill = payservice.suixinfuElectronicBill(channel, billDate, saveDate);
        if (electronicBill == null) {
            return null;
        }
        electronicBillService.saveChack(electronicBill, store.getName());
        return electronicBill;
    }
}
